我在Android上编译了FFmpeg(libffmpeg.so).现在我必须构建像RockPlayer这样的应用程序或使用现有的Android多媒体框架来调用FFmpeg.
你有关于在Android/StageFright上集成FFmpeg的步骤/程序/代码/示例吗?
您能否指导我如何使用此库进行多媒体播放?
我有一个要求,我已经有音频和视频传输流,我需要将其提供给FFmpeg并进行解码/渲染.我怎么能在Android上这样做,因为IOMX API是基于OMX的,不能在这里插入FFmpeg?
另外,我找不到需要用于播放的FFmpeg API的文档.
这是一个两部分问题,所有关于原子性std::shared_ptr
:
1.
据我所知,std::shared_ptr
是唯一的智能指针<memory>
这就是原子.我想知道是否有非原子版本std::shared_ptr
可用(我看不到任何内容<memory>
,所以我也接受标准之外的建议,比如Boost中的建议).我知道boost::shared_ptr
也是原子的(如果BOOST_SP_DISABLE_THREADS
没有定义),但也许有另一种选择?我正在寻找具有相同语义std::shared_ptr
但没有原子性的东西.
2.我明白为什么std::shared_ptr
是原子的; 这有点好.然而,对于每种情况来说都不是很好,而且C++历来有"只为你使用的东西买单"的口号.如果我没有使用多个线程,或者我使用多个线程但是没有跨线程共享指针所有权,则原子智能指针是过度的.我的第二个问题是为什么不是std::shared_ptr
C++ 11 中提供的非原子版本?(假设有一个原因)(如果答案是简单的"非原子版本根本不会考虑"或"从来没有人问非原子版"这很好!).
对于问题#2,我想知道是否有人提出过非原子版shared_ptr
(无论是对Boost还是标准委员会)(不是替换原子版本shared_ptr
,而是与它共存)并且它被击落了具体原因.
以下指针别名示例:
pub unsafe fn f(a: *mut i32, b: *mut i32, x: *const i32) {
*a = *x;
*b = *x;
}
Run Code Online (Sandbox Code Playgroud)
编译成以下程序集(with -C opt-level=s
):
example::f:
push rbp
mov rbp, rsp
mov eax, dword ptr [rdx]
mov dword ptr [rdi], eax
mov eax, dword ptr [rdx]
mov dword ptr [rsi], eax
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
请注意,x
它被解除引用两次.LLVM没有将其视为noalias
.我的第一个想法是避免在赋值中使用指针,而是使用安全引用(因为那些" 遵循LLVM的作用域noalias
模型 ")来给优化器提示:
pub fn g(a: *mut i32, b: *mut i32, x: *const i32) {
let safe_a = unsafe { …
Run Code Online (Sandbox Code Playgroud) 我试过谷歌这个并阅读:
但他们都说得很明显:你不能分配给数组,因为标准是这样说的.这很棒,但我想知道为什么标准不包括对分配数组的支持.标准委员会详细讨论了一些事情,如果他们从未讨论过将阵列分配给我,我会感到惊讶.假设他们已经讨论过,他们必须有一些理由不让数组被分配.
我的意思是,我们可以将一个数组放在一个结构中并分配给结构就好了:
struct wrapper
{
int array[2];
};
struct wrapper a = {{1, 2}};
struct wrapper b = {{3, 4}};
a = b; // legal
Run Code Online (Sandbox Code Playgroud)
但是禁止直接使用数组,即使它有效地完成了同样的事情:
int a[2] = {1, 2};
int b[2] = {3, 4};
a = b; // Not legal
Run Code Online (Sandbox Code Playgroud)
标准委员会禁止分配数组的理由是什么?
首先,我理解为什么virtual
在单继承和通过基指针删除对象方面需要析构函数.这是专门关于多重继承和背后的原因,为什么这个工程.这个问题出现在我的一个大学课程中,没有人(包括教授)确定为什么这有效:
#include <iostream>
struct A
{
virtual ~A()
{
std::cout << "~A" << std::endl;
}
int memberA;
};
struct B
{
virtual ~B()
{
std::cout << "~B" << std::endl;
}
int memberB;
};
struct AB : public A, public B
{
virtual ~AB()
{
std::cout << "~AB" << std::endl;
}
};
int main()
{
AB* ab1 = new AB();
AB* ab2 = new AB();
A* a = ab1;
B* b = ab2;
delete a;
delete b; …
Run Code Online (Sandbox Code Playgroud) 我知道C和C++标准没有规定数字的特定表示(可以是二进制补码,符号和数量等).但我不清楚这些标准(并且无法确定是否已经说明)知道在使用位时是否存在任何特定的限制/保证/保留表示.尤其:
x
,我想检查变量y
以查看它是否是第5位是1,我想知道是否if (x & y)
可行(因为据我所知,这取决于表示的值而不是该位是否实际上是1或0))char c
所有位置为真(设置为c = c | ~c
)并c = c << (CHAR_BIT - 1)
设置高位和c = c ^ (c << 1)
低位更简单的方法,假设我没有做任何假设,我不应该这样,给出这些问题)我想我的整体问题是:C和C++标准是否有关于位和整数的限制/保证/保留表示,尽管事实上没有强制表示整数的表示(如果C和C++标准在这方面有所不同) ,他们的区别是什么?)
我在完成作业时提出了这些问题,这需要我做一些操作(注意这些不是我作业的问题,这些都是"抽象的").
编辑:至于我称之为"位",我的意思是"值形成"位而不包括"填充"位.
互联网上有很多页面都在讨论"file:/// android_asset /"路径(有时候会附加一个s ......)来访问assets文件夹.我无法在此路径/功能上找到任何官方或值得信赖的文档.
这条路是否有适当的文件?Android团队是否记录了它?
我正在为FFmpeg编写补丁,需要调试我的代码.我正在加载一个外部库,为了测试不同的库版本,我将它们放在不同的文件夹中.要选择我想要使用哪一个,我一直在使用DYLD_LIBRARY_PATH=/path/to/lib/dir ./ffmpeg
,并且工作正常.但是当我在lldb
里面尝试时,它崩溃说dyld: Library not loaded
和Reason: image not found
.这曾经在Xcode 7.1之前工作,但我刚刚升级并停止工作.
这是我的MVCE:
#include <stdio.h>
#include <stdlib.h>
int main() {
char* str = getenv("DYLD_LIBRARY_PATH");
if (str) puts(str);
else puts("(null)");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
按如下方式运行此程序会产生输出:
$ ./a.out
(null)
$ DYLD_LIBRARY_PATH=/tmp ./a.out
/tmp
Run Code Online (Sandbox Code Playgroud)
那看起来还不错.但是当我尝试使用lldb时它会失败:
$ DYLD_LIBRARY_PATH=/tmp lldb ./a.out
(lldb) target create "./a.out"
Current executable set to './a.out' (x86_64).
(lldb) run
Process 54255 launched: './a.out' (x86_64)
(null)
Process 54255 exited with status = 0 (0x00000000)
Run Code Online (Sandbox Code Playgroud)
试图在lldb中设置环境变量:
lldb ./a.out
(lldb) …
Run Code Online (Sandbox Code Playgroud) 我想构造一个元组并将结果的一部分分配给一个新变量,并将结果的另一部分分配给现有的.
以下代码说明了intent(这是一个导致无限循环打印的愚蠢示例[0]
):
fn main() {
let mut list = &[0, 1, 2, 3][..];
while !list.is_empty() {
let (head, list) = list.split_at(1);
// An obvious workaround here is to introduce a new variable in the above
// let statement, and then just assign it to list.
println!("{:?}", head);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码创建一个新变量,list
而不是重新分配它.
如果我将代码更改为以下(为了避免let
引入新list
变量),它不会编译:
fn main() {
let mut list = &[0, 1, 2, 3][..];
while !list.is_empty() {
let head;
(head, list) = list.split_at(1);
println!("{:?}", …
Run Code Online (Sandbox Code Playgroud) 我现在正在使用libjpeg来保存JPEG图像.如果有错误,libjpeg的默认行为是调用exit()
,我想避免,因为它不是我的程序的致命错误.的libjpeg 可以让你使用你自己的错误管理器,并授权,如果您使用自己的error_exit()
函数(调用exit()
默认情况下),你必须不控制权返回给调用者.libjpeg建议使用setjmp.h来满足此要求而不是exit()
程序.
但是,我正在编写一个C++程序,我可以访问异常.这个问题的答案表明从回调中抛出异常是安全的(如明确定义的行为).但它没有提到动态库,并且通常的经验法则是不要在动态库边界之间抛出异常.
这是一个例子:
#include <iostream>
#include <jpeglib.h>
#include <cstdio>
#include <stdexcept>
static void handleLibJpegFatalError(j_common_ptr cinfo)
{
(*cinfo->err->output_message)(cinfo);
throw std::runtime_error("error in libjpeg, check stderr");
}
int main()
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* file = std::fopen("out.jpeg", "wb"); // assume this doesn't fail for this example
try
{
cinfo.err = jpeg_std_error(&jerr);
jerr.error_exit = handleLibJpegFatalError;
// let's say this triggers a fatal error …
Run Code Online (Sandbox Code Playgroud)